package com.fyb.basic.lock.thread;

/**
 * 两个线程轮流打印 1~100
 */
public class AlternatePrinting {
    // 当前要打印的数字，从1开始
    private int currentNumber = 1;
    // 锁对象，用于线程同步
    private final Object lock = new Object();

    public static void main(String[] args) {
        AlternatePrinting ap = new AlternatePrinting();

        // 创建奇数打印线程
        Thread oddPrinter = new Thread(() -> {
            ap.printNumber(true);
        });
        oddPrinter.start();

        // 创建偶数打印线程
        Thread evenPrinter = new Thread(() -> {
            ap.printNumber(false);
        });
        evenPrinter.start();
    }

    /**
     * 根据标志打印奇数或偶数
     *
     * @param flag true表示打印奇数，false表示打印偶数
     */
    private void printNumber(boolean flag) {
        // 循环直到打印完100
        while (currentNumber <= 100) {
            synchronized (lock) {
                // 检查当前线程是否应该打印，如果不应该打印，则等待
                while ((flag && currentNumber % 2 == 0) || (!flag && currentNumber % 2 == 1)) {
                    try {
                        // 当前线程等待
                        lock.wait();
                    } catch (InterruptedException e) {
                        // 如果等待过程中线程被中断，抛出运行时异常
                        throw new RuntimeException(e);
                    }
                }

                // 再次检查currentNumber，以防在等待时超过100
                if (currentNumber <= 100) {
                    // 打印当前数字和线程类型
                    System.out.println("Thread " + (flag ? "Odd " : "Even") + ": " + currentNumber);
                    // 递增currentNumber
                    currentNumber++;
                    // 唤醒其他等待线程
                    lock.notifyAll();
                }
            }
        }
    }
}
